import 'package:built_collection/built_collection.dart';
import 'package:equatable/equatable.dart';

part 'collection_sorting.dart';

sealed class CollectionListItem {
  String get id;

  CollectionListItem copyWith({
    String Function()? id,
  });
}

sealed class InbuiltCollectionListItem implements CollectionListItem {
  BuiltMap<String, String> get titles;

  @override
  InbuiltCollectionListItem copyWith({
    String Function()? id,
    BuiltMap<String, String> Function()? titles,
  });
}

sealed class Collection implements CollectionListItem {
  BuiltSet<String> get lexicalItemIds;

  bool get selected;

  bool get highPriority;

  CollectionSorting get sorting;

  @override
  Collection copyWith({
    String Function()? id,
    BuiltSet<String> Function()? lexicalItemIds,
    bool Function()? selected,
    bool Function()? highPriority,
    CollectionSorting Function()? sorting,
  });
}

class InbuiltCollection extends Equatable implements InbuiltCollectionListItem, Collection {
  const InbuiltCollection({
    required this.id,
    required this.titles,
    required this.lexicalItemIds,
    required this.selected,
    required this.highPriority,
    required this.sorting,
  });

  @override
  final String id;

  @override
  final BuiltMap<String, String> titles;

  @override
  final BuiltSet<String> lexicalItemIds;

  @override
  final bool selected;

  @override
  final bool highPriority;

  @override
  final CollectionSorting sorting;

  @override
  List<Object?> get props {
    return [
      id,
      titles,
      lexicalItemIds,
      selected,
      highPriority,
      sorting,
    ];
  }

  @override
  InbuiltCollection copyWith({
    String Function()? id,
    BuiltMap<String, String> Function()? titles,
    BuiltSet<String> Function()? lexicalItemIds,
    bool Function()? selected,
    bool Function()? highPriority,
    CollectionSorting Function()? sorting,
  }) {
    return InbuiltCollection(
      id: id == null ? this.id : id(),
      titles: titles == null ? this.titles : titles(),
      lexicalItemIds: lexicalItemIds == null ? this.lexicalItemIds : lexicalItemIds(),
      selected: selected == null ? this.selected : selected(),
      highPriority: highPriority == null ? this.highPriority : highPriority(),
      sorting: sorting == null ? this.sorting : sorting(),
    );
  }
}

sealed class CollectionFolder implements CollectionListItem {
  BuiltList<Collection> get collections;
}

class InbuiltCollectionFolder extends Equatable
    implements InbuiltCollectionListItem, CollectionFolder {
  const InbuiltCollectionFolder({
    required this.id,
    required this.titles,
    required this.collections,
  });

  @override
  final String id;

  @override
  final BuiltMap<String, String> titles;

  @override
  final BuiltList<InbuiltCollection> collections;

  @override
  List<Object?> get props {
    return [
      id,
      titles,
      collections,
    ];
  }

  @override
  InbuiltCollectionFolder copyWith({
    String Function()? id,
    BuiltMap<String, String> Function()? titles,
    BuiltList<InbuiltCollection> Function()? collections,
  }) {
    return InbuiltCollectionFolder(
      id: id == null ? this.id : id(),
      titles: titles == null ? this.titles : titles(),
      collections: collections == null ? this.collections : collections(),
    );
  }
}

sealed class CustomCollectionListItem implements CollectionListItem {
  String get title;

  @override
  CollectionListItem copyWith({
    String Function()? id,
    String Function()? title,
  });
}

class CustomCollection extends Equatable implements CustomCollectionListItem, Collection {
  const CustomCollection({
    required this.id,
    required this.title,
    required this.lexicalItemIds,
    required this.selected,
    required this.highPriority,
    required this.sorting,
  });

  @override
  final String id;

  @override
  final String title;

  @override
  final BuiltSet<String> lexicalItemIds;

  @override
  final bool selected;

  @override
  final bool highPriority;

  @override
  final CollectionSorting sorting;

  @override
  List<Object?> get props {
    return [
      id,
      title,
      lexicalItemIds,
      selected,
      highPriority,
      sorting,
    ];
  }

  @override
  CustomCollection copyWith({
    String Function()? id,
    String Function()? title,
    BuiltSet<String> Function()? lexicalItemIds,
    bool Function()? selected,
    bool Function()? highPriority,
    CollectionSorting Function()? sorting,
  }) {
    return CustomCollection(
      id: id == null ? this.id : id(),
      title: title == null ? this.title : title(),
      lexicalItemIds: lexicalItemIds == null ? this.lexicalItemIds : lexicalItemIds(),
      selected: selected == null ? this.selected : selected(),
      highPriority: highPriority == null ? this.highPriority : highPriority(),
      sorting: sorting == null ? this.sorting : sorting(),
    );
  }
}

class CustomCollectionFolder extends Equatable
    implements CustomCollectionListItem, CollectionFolder {
  const CustomCollectionFolder({
    required this.id,
    required this.title,
    required this.collections,
  });

  @override
  final String id;

  @override
  final String title;

  @override
  final BuiltList<CustomCollection> collections;

  @override
  List<Object?> get props {
    return [
      id,
      title,
      collections,
    ];
  }

  @override
  CustomCollectionFolder copyWith({
    String Function()? id,
    String Function()? title,
    BuiltList<CustomCollection> Function()? collections,
  }) {
    return CustomCollectionFolder(
      id: id == null ? this.id : id(),
      title: title == null ? this.title : title(),
      collections: collections == null ? this.collections : collections(),
    );
  }
}
